return NULL;
}
+static void
+generate_grab_broken_event (GdkWindow *window,
+ gboolean keyboard,
+ gboolean implicit,
+ GdkWindow *grab_window)
+{
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GdkEvent event;
+
+ event.type = GDK_GRAB_BROKEN;
+ event.grab_broken.window = window;
+ event.grab_broken.send_event = 0;
+ event.grab_broken.keyboard = keyboard;
+ event.grab_broken.implicit = implicit;
+ event.grab_broken.grab_window = grab_window;
+
+ gdk_event_put (&event);
+ }
+}
+
+
GdkGrabStatus
gdk_keyboard_grab (GdkWindow *window,
gint owner_events,
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
if (_gdk_quartz_keyboard_grab_window)
- gdk_keyboard_ungrab (time);
+ {
+ generate_grab_broken_event (_gdk_quartz_keyboard_grab_window,
+ TRUE, FALSE, window);
+ g_object_unref (_gdk_quartz_keyboard_grab_window);
+ }
_gdk_quartz_keyboard_grab_window = g_object_ref (window);
keyboard_grab_owner_events = owner_events;
if (_gdk_quartz_pointer_grab_window)
{
- if (!pointer_grab_implicit)
- return GDK_GRAB_ALREADY_GRABBED;
+ if (_gdk_quartz_pointer_grab_window == window && !pointer_grab_implicit)
+ return GDK_GRAB_ALREADY_GRABBED;
else
- pointer_ungrab_internal (TRUE);
+ {
+ if (_gdk_quartz_pointer_grab_window != window)
+ generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
+ FALSE, pointer_grab_implicit, window);
+ pointer_ungrab_internal (TRUE);
+ }
}
return pointer_grab_internal (window, owner_events, event_mask,
return mask;
}
case NSKeyDown:
- return GDK_KEY_PRESS_MASK;
case NSKeyUp:
- return GDK_KEY_RELEASE_MASK;
+ case NSFlagsChanged:
+ {
+ GdkEventType type = _gdk_quartz_key_event_type (nsevent);
+ switch (type)
+ {
+ case GDK_KEY_PRESS: return GDK_KEY_PRESS_MASK;
+ case GDK_KEY_RELEASE: return GDK_KEY_RELEASE_MASK;
+ case GDK_NOTHING: return 0;
+ default: g_assert_not_reached ();
+ }
+ }
default:
g_assert_not_reached ();
}
case NSKeyDown:
case NSKeyUp:
+ case NSFlagsChanged:
{
GdkWindow *keyboard_window;
GdkEventMask event_mask;
}
static GdkEvent *
-create_key_event (GdkWindow *window, NSEvent *nsevent)
+create_key_event (GdkWindow *window, NSEvent *nsevent, GdkEventType type)
{
- GdkEventType event_type;
GdkEvent *event;
- switch ([nsevent type])
- {
- case NSKeyDown:
- event_type = GDK_KEY_PRESS;
- break;
- case NSKeyUp:
- event_type = GDK_KEY_RELEASE;
- break;
- default:
- g_assert_not_reached ();
- }
-
- event = gdk_event_new (event_type);
+ event = gdk_event_new (type);
event->key.window = window;
event->key.time = get_event_time (nsevent);
event->key.state = get_keyboard_modifiers_from_nsevent (nsevent);
&event->key.keyval,
NULL, NULL, NULL);
+ GDK_NOTE(EVENTS,
+ g_message ("key %s:\t\twindow: %p key: %12s %d",
+ type == GDK_KEY_PRESS ? "press" : "release",
+ event->key.window,
+ event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
+ event->key.keyval));
return event;
}
}
case NSKeyDown:
case NSKeyUp:
- event = create_key_event (window, nsevent);
- append_event (event);
- return TRUE;
- break;
-
+ case NSFlagsChanged:
+ {
+ GdkEventType type = _gdk_quartz_key_event_type (nsevent);
+ if (type == GDK_NOTHING)
+ return FALSE;
+
+ event = create_key_event (window, nsevent, type);
+ append_event (event);
+ return TRUE;
+ break;
+ }
default:
NSLog(@"Untranslated: %@", nsevent);
}
#include <config.h>
#include <Carbon/Carbon.h>
+#include <AppKit/NSEvent.h>
#include "gdk.h"
#include "gdkkeysyms.h"
const static struct {
guint keycode;
guint keyval;
+ unsigned int modmask; /* So we can tell when a mod key is pressed/released */
} known_keys[] = {
- { 55, GDK_Meta_L },
- { 56, GDK_Shift_L },
- { 57, GDK_Caps_Lock },
- { 58, GDK_Alt_L },
- { 59, GDK_Control_L },
- { 60, GDK_Shift_R },
- { 61, GDK_Alt_R },
- { 62, GDK_Control_R },
- { 122, GDK_F1 },
- { 120, GDK_F2 },
- { 99, GDK_F3 },
- { 118, GDK_F4 },
- { 96, GDK_F5 },
- { 97, GDK_F6 },
- { 98, GDK_F7 },
- { 100, GDK_F8 },
- { 101, GDK_F9 },
- { 109, GDK_F10 },
- { 103, GDK_F11 },
- { 111, GDK_F12 },
- { 105, GDK_F13 },
- { 107, GDK_F14 },
- { 113, GDK_F15 },
+ { 54, GDK_Meta_R, NSCommandKeyMask },
+ { 55, GDK_Meta_L, NSCommandKeyMask },
+ { 56, GDK_Shift_L, NSShiftKeyMask },
+ { 57, GDK_Caps_Lock, NSAlphaShiftKeyMask },
+ { 58, GDK_Alt_L, NSAlternateKeyMask },
+ { 59, GDK_Control_L, NSControlKeyMask },
+ { 60, GDK_Shift_R, NSShiftKeyMask },
+ { 61, GDK_Alt_R, NSAlternateKeyMask },
+ { 62, GDK_Control_R, NSControlKeyMask },
+ { 122, GDK_F1, 0 },
+ { 120, GDK_F2, 0 },
+ { 99, GDK_F3, 0 },
+ { 118, GDK_F4, 0 },
+ { 96, GDK_F5, 0 },
+ { 97, GDK_F6, 0 },
+ { 98, GDK_F7, 0 },
+ { 100, GDK_F8, 0 },
+ { 101, GDK_F9, 0 },
+ { 109, GDK_F10, 0 },
+ { 103, GDK_F11, 0 },
+ { 111, GDK_F12, 0 },
+ { 105, GDK_F13, 0 },
+ { 107, GDK_F14, 0 },
+ { 113, GDK_F15, 0 },
};
const static struct {
return TRUE;
}
+
+/* What sort of key event is this? Returns one of
+ * GDK_KEY_PRESS, GDK_KEY_RELEASE, GDK_NOTHING (should be ignored)
+ */
+GdkEventType _gdk_quartz_key_event_type (NSEvent *event)
+{
+ unsigned short keycode;
+ unsigned int flags;
+ int i;
+
+ switch ([event type])
+ {
+ case NSKeyDown: return GDK_KEY_PRESS;
+ case NSKeyUp: return GDK_KEY_RELEASE;
+ case NSFlagsChanged: break; /* Continue... */
+ default: g_assert_not_reached ();
+ }
+
+ /* For flags-changed events, we have to find the special key that caused the
+ * event, and see if it's in the modifier mask. */
+ keycode = [event keyCode];
+ flags = [event modifierFlags];
+
+ for (i = 0; i < G_N_ELEMENTS (known_keys); i++)
+ {
+ if (known_keys[i].keycode == keycode)
+ {
+ if (flags & known_keys[i].modmask)
+ return GDK_KEY_PRESS;
+ else
+ return GDK_KEY_RELEASE;
+ }
+ }
+
+ /* Some keypresses (eg: Expose' activations) seem to trigger flags-changed
+ * events for no good reason. Ignore them! */
+ return GDK_NOTHING;
+}